package ruler.rules;

import java.util.ArrayList;
import java.util.HashMap;

import android.os.Parcel;
import android.os.Parcelable;

public abstract class Rule implements Parcelable {

	public static enum RULE_TYPE {
		APP, SERVICE
	}

	public static enum DEVICE_TYPE {
		GPS, WIFI
	}

	protected int id;
	protected String name;
	protected String description;
	protected boolean enable = true;
	protected boolean selected = false;

	protected DEVICE_TYPE device_type = DEVICE_TYPE.WIFI;
	protected boolean device_enable = true;

	protected RULE_TYPE rule_type = RULE_TYPE.APP;
	protected String packageName;
	protected boolean whenRunning = true;

	public Rule() {
	}

	public Rule(String name) {
		this.name = name;
	}

	public Rule(int id, String name, String description,
			DEVICE_TYPE device_type, RULE_TYPE rule_type, String packageName,
			boolean whenRunning, boolean enable_device) {
		this.id = id;
		this.name = name;
		this.description = description;
		this.device_type = device_type;
		this.rule_type = rule_type;
		this.packageName = packageName;
		this.whenRunning = whenRunning;
		this.device_enable = enable_device;
		this.selected = false;
		this.enable = false;
	}

	public Rule(Rule rule) {
		if (rule != null) {
			this.id = rule.getId();
			this.name = rule.getName();
			this.description = rule.getDescription();
			this.device_type = rule.getDeviceType();
			this.rule_type = rule.getRuleType();
			this.packageName = rule.getPackageName();
			this.whenRunning = rule.getWhenIsRunning();
			this.device_enable = rule.getDeviceEnable();
			this.selected = rule.isSelected();
			this.enable = rule.isEnable();
		}
	}

	public Rule(Parcel in) {
		this.id = in.readInt();
		this.name = in.readString();
		this.description = in.readString();
		this.packageName = in.readString();
		this.enable = (Boolean) in.readValue(Boolean.class.getClassLoader());
		this.selected = (Boolean) in.readValue(Boolean.class.getClassLoader());
		this.device_enable = (Boolean) in.readValue(Boolean.class
				.getClassLoader());
		this.whenRunning = (Boolean) in.readValue(Boolean.class
				.getClassLoader());
		this.device_type = (DEVICE_TYPE) in.readValue(DEVICE_TYPE.class
				.getClassLoader());
		this.rule_type = (RULE_TYPE) in.readValue(RULE_TYPE.class
				.getClassLoader());
	}

	public int getId() {
		return this.id;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public void setSelected(boolean selected) {
		this.selected = selected;
	}

	public boolean isSelected() {
		return this.selected;
	}

	public void setEnable(boolean b) {
		this.enable = b;
	}
	
	public boolean getWhenIsRunning() {
		return this.whenRunning;
	}
	
	public void setWhenIsRunning(boolean value) {
		this.whenRunning = value;
	}

	public boolean isEnable() {
		return this.enable;
	}
	
	public RULE_TYPE getRuleType() {
		return this.rule_type;
	}
	
	public void setRuleType(RULE_TYPE type) {
		this.rule_type = type;	
	}

	public DEVICE_TYPE getDeviceType() {
		return this.device_type;
	}
	
	public void setDeviceType(DEVICE_TYPE type) {
		this.device_type = type;
	}

	public boolean getDeviceEnable() {
		return this.device_enable;
	}
	
	public void setDeviceEnable(boolean state) {
		this.device_enable = state;
	}

	public String getPackageName() {
		return this.packageName;
	}
	
	public void setPackageName(String name){
		this.packageName = name;
	}

	public boolean isInConflictWith(Rule otherRule) {
		if (this.device_type.equals(otherRule.device_type)) {
			if (this.packageName.equals(otherRule.getPackageName())) {
				if (this.device_enable == otherRule.device_enable) {
					if (this.whenRunning != otherRule.whenRunning) {
						return true;
					}
				} else {
					if (this.whenRunning == otherRule.whenRunning) {
						return true;
					}
				}
			}
		}
		return false;
	}
	
	public boolean isInConflictWithOne(ArrayList<Rule> rules){
		for(Rule r: rules){
			if (this.isInConflictWith(r))
				return true;
		}
		return false;
	}	
	
	public void writeToParcel(Parcel parcel, int flags) {
		parcel.writeInt(this.id);
		parcel.writeString(name);
		parcel.writeString(description);
		parcel.writeString(packageName);
		parcel.writeValue(new Boolean(this.enable));
		parcel.writeValue(new Boolean(this.selected));
		parcel.writeValue(new Boolean(this.device_enable));
		parcel.writeValue(new Boolean(this.whenRunning));
		parcel.writeValue(device_type);
		parcel.writeValue(this.rule_type);
	}

	public int describeContents() {
		return 0;
	}

	public abstract boolean isValid(HashMap<String, RULE_TYPE> hasMap);

}
